package com.fly.swt.thread;

import java.util.concurrent.TimeUnit;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;

/**
 * 
 * 多线程更新UI
 * 
 * @author 00fly
 * @version [版本号, 2020年5月4日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class ThreadUIExample
{
    Display display;
    
    Shell shell;
    
    List list;
    
    int threadNum = 10, runTime = 5000;
    
    /**
     * 默认构造函数
     */
    public ThreadUIExample()
    {
        display = new Display();
        shell = new Shell(display, SWT.ON_TOP | SWT.MIN | SWT.MAX | SWT.CLOSE);
        shell.setText("SWT Thread Test");
        shell.setLayout(new GridLayout(1, true));
        createContents();
        shell.setSize(800, 600);
        shell.open();
        while (!shell.isDisposed())
        {
            if (!display.readAndDispatch())
            {
                display.sleep();
            }
        }
        display.dispose();
    }
    
    /**
     * 创建Content
     * 
     * @see [类、类#方法、类#成员]
     */
    private void createContents()
    {
        // 添加列表
        list = new List(shell, SWT.BORDER);
        list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        for (int index = 0; index < threadNum; index++)
        {
            list.add("text " + (index + 1));
        }
        Button startBtn = new Button(shell, SWT.PUSH);
        startBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        startBtn.setText("start run");
        
        // 事件监听
        startBtn.addSelectionListener(new SelectionAdapter()
        {
            @Override
            public void widgetSelected(SelectionEvent e)
            {
                startThread();
            }
        });
    }
    
    /**
     * Main
     * 
     * @param args
     * @see [类、类#方法、类#成员]
     */
    public static void main(String[] args)
    {
        new ThreadUIExample();
    }
    
    /**
     * 启动多线程
     * 
     * 此方法用于执行需要很长时间，而在其执行期间又不会影响其他方法的执行<br>
     * BusyIndicator.showWhile(shell.getDisplay(), refresh);是关键<br>
     * 如果没有这一句则，执行此方法时，其他方法不能运行<br>
     * 这个方法的必须包含两个Runnable的实现<br>
     * 其中外层用于 BusyIndicator.showWhile方法中作为参数<br>
     * 长时间的运行代码应该放在里面的一个Runnable实现的run方法中
     */
    public void startThread()
    {
        for (int index = 0; index < threadNum; index++)
        {
            int listIndex = index;
            Runnable refresh = new Runnable()
            {
                @Override
                public void run()
                {
                    // 处理线程( 匿名内部类)
                    Runnable runOne = new Runnable()
                    {
                        @Override
                        public void run()
                        {
                            final long start = System.currentTimeMillis();
                            while ((System.currentTimeMillis() - start) < runTime)
                            {
                                display.syncExec(new Runnable()
                                {
                                    @Override
                                    public void run()
                                    {
                                        if (list.isDisposed())
                                        {
                                            return;
                                        }
                                        Long time = System.currentTimeMillis() - start;
                                        list.setItem(listIndex, String.format("No.%s %s", listIndex, time));
                                    }
                                });
                                try
                                {
                                    TimeUnit.MICROSECONDS.sleep(1000);
                                }
                                catch (InterruptedException e)
                                {
                                }
                            }
                        }
                    };
                    new Thread(runOne).start();
                }
            };
            // 添加监听
            BusyIndicator.showWhile(shell.getDisplay(), refresh);// 这一句很关键
        }
    }
    
}